<html>
    <head>
        <title>数据播种引擎服务  IDataSeeder</title>
    </head>
    <body>
        <script>
              /*
                        五、IDataSeeder  数据播种引擎服务   

                                你通常不需要使用 IDataSeeder服务，因为如果你已经使用了 "启动模板"，它就已经完成了。

                                但是建议你阅读当前文档以了解数据种子系统背后的设计。

                                IDataSeeder 服务是用于播种初始数据的主要服务。 它的使用很简单：

                                                public class MyService : ITransientDependency
                                                {
                                                    private readonly IDataSeeder _dataSeeder;

                                                    public MyService(IDataSeeder dataSeeder)
                                                    {
                                                        _dataSeeder = dataSeeder; // 注入数据播种引擎服务
                                                    }

                                                    public async Task FooAsync()
                                                    {
                                                        await _dataSeeder.SeedAsync(); // 执行数据播种逻辑

                                                    }
                                                }

                                你可以注入IDataSeeder并在需要时使用它来播种初始数据。

                                它在内部调用所有 IDataseeder的实现来完成数据播种。



                                1、使用数据播种上下文(DataSeedContext)传递配置参数
                            
                                        你还可以通过数据播种上下文 DataSeedContext 来讲配置参数传递给数据播种程序(DataSeedContributor)

                                            eg:
                                                await _dataSeeder.SeedAsync(
                                                    new DataSeedContext()
                                                        .WithProperty("MyProperty1", "MyValue1")
                                                        .WithProperty("MyProperty2", 42)
                                                );

                                        然后数据播种程序(DataSeedContributor)可以在SeedAsync方法中使用这些配置参数。


                                        如果一个模块的数据播种操作需要配置参数，那它的文档中应该声明。

                                        例如，如果你提供 IDentity 模块可以使用 AdminEmail 和 AdminPassword参数来执行默认账户的邮箱和密码（否则使用框架默认的密码）。


                                2、使用独立的播种工作单元 SeedInSeptarateUowAsync() 方法 

                                        默认种子将在一个工作单元中，可能会使用事务。

                                        如果有多个 IDataSeedContributor 或者写入的数据过多，可能会导致"数据库超时错误"。

                                        我们为 IDataSeedContributor 服务提供了 SeedInSeptarateUowAsync (在独立的工作单元中播种) 方法。
                                        为每个 IDataSeedContributor 创建一个单独的工作单元：

                                            public static Task SeedInSeparateUowAsync(this IDataSeeder seeder, Guid? tenantId = null, AbpUnitOfWorkOptions options = null, bool requiresNew = false)


                                3、在那里播种？ 如何播种?

                                        应用程序启动模板附带一个YourProjectName**. DbMigrator**项目（下图中的Acme.BookStore.DbMigrator），

                                        它是一个控制台应用程序，负责迁移数据库模型（用于关系数据库）和种子初始数据：

                                        此控制台应用程序已为你正确配置。它甚至支持多租户场景，其中每个租户都有自己的数据库（迁移和种子所有必要的数据库）。

                                        每当你将解决方案的新版本部署到服务器时，预计都会运行此DbMigrator应用程序。

                                        它将迁移你的数据库模式（创建新表/字段…等）并播种正确运行新版本解决方案所需的新初始数据。

                                        然后你可以部署/启动你的实际应用程序。

                                        即使你正在使用MongoDB或其他非关系型数据库（不需要模式迁移），也建议使用DbMigrator应用程序来播种数据或执行数据迁移。



                                        拥有这样一个单独的控制台应用程序有几个优点:

                                                ①、你可以在更新你的应用程序之前运行它，因此你的应用程序将在就绪的数据库上运行。

                                                ②、与播种初始数据本身相比，你的应用程序启动速度更快。

                                                ③、你的应用程序可以在集群环境上正确运行（你的应用程序的多个实例同时运行）。如果你在应用程序启动时播种数据，在这种情况下你会遇到冲突。

                                4、开发时的注意点
                                
                                        我们建议在开发中使用相同的方法。

                                        每当你创建数据库迁移时(例如，使用EF Core Add-Migration命令)  或更改数据种子代码(稍后将解释)时，运行DbMigrator应用程序。
                                        (你可以继续使用EF Core 的标准 Update-Database命令，但是如果你创建了新的种子数据，它将不会播种)。

                                5、关于测试

                                        你可能还希望为自动化测试播种数据，因此希望使用IDataSeeder.SeedAsync()。
                                        
                                        在应用程序启动模板中，它是在TestBase项目的YourProjectNameTestBaseModule类的OnApplicationInitialization方法中完成的。

                                        除了标准种子数据（也用于生产）之外，你可能希望为自动化测试独有的其他数据播种。
                                        
                                        如果是这样，你可以在测试项目中创建一个新的数据种子贡献者，以处理更多数据。
                    */
        </script>
    </body>
</html>